﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CkSoftware.GroupMeChatModule.Components;

namespace CkSoftware.GroupMeChatModule.Managers
{
	public class GroupMeAuthManager
	{
		private static readonly Lazy<GroupMeAuthManager> ManagerInstance = new Lazy<GroupMeAuthManager>(() => new GroupMeAuthManager());
		private static readonly Lazy<Dictionary<int, string>> AccessTokens = new Lazy<Dictionary<int, string>>(() => new Dictionary<int, string>());
		private static readonly Lazy<Dictionary<string, string>> AnonymousAccessTokens = new Lazy<Dictionary<string, string>>(() => new Dictionary<string, string>());

		public static GroupMeAuthManager Instance
		{
			get { return ManagerInstance.Value; }
		}

		private GroupMeAuthManager()
		{}

		public string GetAuthTokenForUser(int userId)
		{
			if (userId <= 0)
			{
				return string.Empty;
			}

			if (AccessTokens.Value.ContainsKey(userId))
			{
				return AccessTokens.Value[userId];
			}

			return string.Empty;
		}

		public void SetAuthTokenForUser(int userId, string authToken)
		{
			if (userId <= 0)
			{
				return;
			}

			if (AccessTokens.Value.ContainsKey(userId))
			{
				AccessTokens.Value[userId] = authToken;
				return;
			}

			AccessTokens.Value.Add(userId, authToken);
		}

		public string GetAuthTokenForAnonymous(string sessionId)
		{
			if (string.IsNullOrEmpty(sessionId))
			{
				return string.Empty;
			}

			if (AnonymousAccessTokens.Value.ContainsKey(sessionId))
			{
				return AnonymousAccessTokens.Value[sessionId];
			}

			return string.Empty;
		}

		public string GetAuthTokenForUserOrAnonymous(int userId, string sessionId)
		{
			var authToken = GetAuthTokenForUser(userId);

			if (string.IsNullOrEmpty(authToken))
			{
				authToken = GetAuthTokenForAnonymous(sessionId);
			}

			return authToken;
		}

		public void SetAuthTokenForAnonymous(string sessionId, string authToken)
		{
			if (string.IsNullOrEmpty(sessionId))
			{
				return;
			}

			if (AnonymousAccessTokens.Value.ContainsKey(sessionId))
			{
				AnonymousAccessTokens.Value[sessionId] = authToken;
				return;
			}

			AnonymousAccessTokens.Value.Add(sessionId, authToken);
		}

		public bool HavePermanentLogin(int userId)
		{
			if (userId <= 0)
			{
				return false;
			}

			var permanentLogonController = new PermanentGroupMeLogonsController();
			var permanentLogon = permanentLogonController.GetItem(userId);

			if (permanentLogon != null && !string.IsNullOrEmpty(permanentLogon.GroupMeAccessToken))
			{
				return true;
			}

			return false;
		}

		public bool HaveAuthTokenForUser(int userId)
		{
			if (userId <= 0)
			{
				return false;
			}

			if (AccessTokens.Value.ContainsKey(userId) && !string.IsNullOrEmpty(AccessTokens.Value[userId]))
			{
				return true;
			}

			TryLoadingAuthTokenFromPermanentLogin(userId);

			if (AccessTokens.Value.ContainsKey(userId) && !string.IsNullOrEmpty(AccessTokens.Value[userId]))
			{
				return true;
			}

			return false;
		}

		public bool HaveAuthTokenForAnonymous(string sessionId)
		{
			if (string.IsNullOrEmpty(sessionId))
			{
				return false;
			}

			if (AnonymousAccessTokens.Value.ContainsKey(sessionId) && !string.IsNullOrEmpty(AnonymousAccessTokens.Value[sessionId]))
			{
				return true;
			}

			return false;
		}

		private void TryLoadingAuthTokenFromPermanentLogin(int userId)
		{
			if (userId <= 0)
			{
				return;
			}

			var permanentLogonController = new PermanentGroupMeLogonsController();
			var permanentLogon = permanentLogonController.GetItem(userId);

			if (permanentLogon != null && !string.IsNullOrEmpty(permanentLogon.GroupMeAccessToken))
			{
				AccessTokens.Value.Add(userId, permanentLogon.GroupMeAccessToken);
			}
		}
	}
}